```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>SpringSession学习文档 | 技术小馆</title>
    <link href="https://cdn.staticfile.org/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
    <link href="https://cdn.staticfile.org/tailwindcss/2.2.19/tailwind.min.css" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;500;600;700&family=Noto+Sans+SC:wght@300;400;500;700&display=swap" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/mermaid@latest/dist/mermaid.min.js"></script>
    <style>
        body {
            font-family: 'Noto Sans SC', sans-serif;
            color: #333;
            line-height: 1.6;
            background-color: #f8f9fa;
        }
        .hero {
            background: linear-gradient(135deg, #6e8efb, #a777e3);
            color: white;
        }
        .prose {
            max-width: 900px;
        }
        .card {
            transition: all 0.3s ease;
            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
        }
        .card:hover {
            transform: translateY(-5px);
            box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);
        }
        .solution-card {
            border-left: 4px solid;
        }
        .solution-card:hover {
            border-left-width: 6px;
        }
        .code-block {
            background-color: #282c34;
            color: #abb2bf;
            border-radius: 6px;
            font-family: monospace;
        }
        .code-block pre {
            margin: 0;
            padding: 1rem;
            overflow-x: auto;
        }
        .divider {
            height: 1px;
            background: linear-gradient(to right, transparent, rgba(0,0,0,0.1), transparent);
        }
        .feature-icon {
            width: 48px;
            height: 48px;
            display: flex;
            align-items: center;
            justify-content: center;
            border-radius: 50%;
            margin-right: 1rem;
            flex-shrink: 0;
        }
    </style>
</head>
<body class="min-h-screen flex flex-col">
    <!-- Hero Section -->
    <section class="hero py-20 px-4 text-center">
        <div class="container mx-auto">
            <h1 class="text-4xl md:text-5xl font-bold mb-6">SpringSession学习文档</h1>
            <p class="text-xl md:text-2xl mb-8 opacity-90">全面解析分布式系统中的会话管理解决方案</p>
            <div class="max-w-3xl mx-auto bg-white bg-opacity-10 p-6 rounded-lg">
                <p class="text-lg">HttpSession是通过Servlet容器创建和管理的，但在分布式集群环境下如何保证不同web站点能共享同一份session数据？SpringSession提供了优雅的解决方案。</p>
            </div>
        </div>
    </section>

    <!-- Main Content -->
    <main class="flex-grow container mx-auto px-4 py-12">
        <div class="prose mx-auto">
            <!-- Session共享问题 -->
            <section class="mb-16">
                <h2 class="text-3xl font-bold mb-6 text-gray-800 border-b pb-2 flex items-center">
                    <i class="fas fa-exclamation-triangle text-yellow-500 mr-3"></i>
                    Session共享问题
                </h2>
                <p class="mb-6">HttpSession是通过Servlet容器创建和管理的，像Tomcat/Jetty都是保存在内存中的。而如果我们把web服务器搭建成分布式的集群，然后利用LVS或Nginx做负载均衡，那么来自同一用户的Http请求将有可能被分发到两个不同的web站点中去。</p>
                
                <div class="bg-white rounded-lg overflow-hidden shadow-md mb-6">
                    <img src="https://cdn.nlark.com/yuque/0/2024/png/21449790/1711248128602-578ccfb7-4744-4ac0-90cc-070337bde516.png" alt="Session共享问题图示" class="w-full">
                </div>
                
                <p class="text-lg font-medium text-gray-700">那么问题就来了，如何保证不同的web站点能够共享同一份session数据呢？</p>
            </section>

            <!-- Session共享解决方案 -->
            <section class="mb-16">
                <h2 class="text-3xl font-bold mb-8 text-gray-800 border-b pb-2 flex items-center">
                    <i class="fas fa-lightbulb text-blue-500 mr-3"></i>
                    Session共享解决方案
                </h2>
                
                <!-- 解决方案1 -->
                <div class="solution-card bg-white rounded-lg p-6 mb-8 border-l-4 border-blue-500">
                    <h3 class="text-2xl font-semibold mb-4 text-gray-800 flex items-center">
                        <i class="fas fa-copy text-blue-500 mr-2"></i>
                        Session复制
                    </h3>
                    <div class="bg-white rounded-lg overflow-hidden shadow-sm mb-4">
                        <img src="https://cdn.nlark.com/yuque/0/2023/png/21449790/1692180731285-88813427-01f3-4b0b-8928-31312d769d27.png" alt="Session复制图示" class="w-full">
                    </div>
                    <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
                        <div class="bg-green-50 p-4 rounded-lg">
                            <h4 class="font-semibold text-green-700 mb-2 flex items-center">
                                <i class="fas fa-check-circle mr-2"></i>
                                优点
                            </h4>
                            <p>web-server (Tomcat) 原生支持，只需要修改配置文件</p>
                        </div>
                        <div class="bg-red-50 p-4 rounded-lg">
                            <h4 class="font-semibold text-red-700 mb-2 flex items-center">
                                <i class="fas fa-times-circle mr-2"></i>
                                缺点
                            </h4>
                            <ul class="list-disc pl-5">
                                <li>session同步需要数据传输，占用大量网络带宽，降低了服务器群的业务处理能力</li>
                                <li>任意一台web-server保存的数据都是所有web-server的session总和，受到内存限制无法水平扩展更多的web-server</li>
                                <li>大型分布式集群情况下，由于所有web-server都全量保存数据，所以此方案不可取。</li>
                            </ul>
                        </div>
                    </div>
                </div>
                
                <!-- 解决方案2 -->
                <div class="solution-card bg-white rounded-lg p-6 mb-8 border-l-4 border-purple-500">
                    <h3 class="text-2xl font-semibold mb-4 text-gray-800 flex items-center">
                        <i class="fas fa-cookie text-purple-500 mr-2"></i>
                        客户端存储
                    </h3>
                    <div class="bg-white rounded-lg overflow-hidden shadow-sm mb-4">
                        <img src="https://cdn.nlark.com/yuque/0/2023/png/21449790/1692180731414-ad2ed162-5f29-4038-ace8-2eabd8dcb411.png" alt="客户端存储图示" class="w-full">
                    </div>
                    <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
                        <div class="bg-green-50 p-4 rounded-lg">
                            <h4 class="font-semibold text-green-700 mb-2 flex items-center">
                                <i class="fas fa-check-circle mr-2"></i>
                                优点
                            </h4>
                            <p>服务器不需存储session,用户保存自己的session信息到cookie中，节省服务端资源。</p>
                        </div>
                        <div class="bg-red-50 p-4 rounded-lg">
                            <h4 class="font-semibold text-red-700 mb-2 flex items-center">
                                <i class="fas fa-times-circle mr-2"></i>
                                缺点
                            </h4>
                            <p class="font-medium mb-2">这只是一种思路，不会使用该方式，具体原因如下：</p>
                            <ul class="list-disc pl-5">
                                <li>每次http请求，携带用户在cookie中的完整信息，浪费网络带宽。</li>
                                <li>session数据放在cookie中，cookie有长度限制4K,不能保存大量信息。</li>
                                <li>session数据放在cookie中，存在泄漏、算改、窃取等安全隐患。</li>
                            </ul>
                        </div>
                    </div>
                </div>
                
                <!-- 解决方案3 -->
                <div class="solution-card bg-white rounded-lg p-6 mb-8 border-l-4 border-green-500">
                    <h3 class="text-2xl font-semibold mb-4 text-gray-800 flex items-center">
                        <i class="fas fa-project-diagram text-green-500 mr-2"></i>
                        Hash一致性
                    </h3>
                    <div class="bg-white rounded-lg overflow-hidden shadow-sm mb-4">
                        <img src="https://cdn.nlark.com/yuque/0/2023/png/21449790/1692180731503-0508de41-504a-4b15-a080-6edd420b836a.png" alt="Hash一致性图示" class="w-full">
                    </div>
                    <p class="mb-4">利用ip_hash的一致性，浏览器不变，IP不变，让每一次访问都落在同一个服务器上。同时也可以配合id值，比如图中的sid=456的请求每次落在第一个服务器，sid=123的请求每次落在第二个服务器。</p>
                    <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
                        <div class="bg-green-50 p-4 rounded-lg">
                            <h4 class="font-semibold text-green-700 mb-2 flex items-center">
                                <i class="fas fa-check-circle mr-2"></i>
                                优点
                            </h4>
                            <ul class="list-disc pl-5">
                                <li>只需要改nginx配置，不需要修改应用代码。</li>
                                <li>负载均衡，只要hash属性的值分布是均匀的，多台web-server的负载是均衡的。</li>
                                <li>可以支持web-server水平扩展(session同步法是不行的，受内存限制)。</li>
                            </ul>
                        </div>
                        <div class="bg-red-50 p-4 rounded-lg">
                            <h4 class="font-semibold text-red-700 mb-2 flex items-center">
                                <i class="fas fa-times-circle mr-2"></i>
                                缺点
                            </h4>
                            <ul class="list-disc pl-5">
                                <li>session还是存在web-server中的，所以web-server重启可能导致部分session丢失，影响业务，如部分用户需要重新登录。</li>
                                <li>如果web-server水平扩展，rehash后session重新分布,也会有一部分用户路由不到正确的session。</li>
                            </ul>
                        </div>
                    </div>
                    <div class="mt-4 bg-blue-50 p-4 rounded-lg">
                        <p class="text-blue-700"><strong>注意：</strong>但是以上缺点问题也不是很大，因为session本来都是有有效期的。所以这两种反向代理的方式可以使用</p>
                    </div>
                </div>
                
                <!-- 解决方案4 -->
                <div class="solution-card bg-white rounded-lg p-6 mb-8 border-l-4 border-orange-500">
                    <h3 class="text-2xl font-semibold mb-4 text-gray-800 flex items-center">
                        <i class="fas fa-database text-orange-500 mr-2"></i>
                        统一存储
                    </h3>
                    <div class="bg-white rounded-lg overflow-hidden shadow-sm mb-4">
                        <img src="https://cdn.nlark.com/yuque/0/2023/png/21449790/1692180731607-2d4d9d9e-7f9b-4042-8ae2-690dbe4ca601.png" alt="统一存储图示" class="w-full">
                    </div>
                    <p class="mb-4">将session存储到数据库(Redis)中，每次都从数据库中获取。</p>
                    <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
                        <div class="bg-green-50 p-4 rounded-lg">
                            <h4 class="font-semibold text-green-700 mb-2 flex items-center">
                                <i class="fas fa-check-circle mr-2"></i>
                                优点
                            </h4>
                            <ul class="list-disc pl-5">
                                <li>没有安全隐患</li>
                                <li>可以水平扩展，数据库/缓存水平切分即可</li>
                                <li>web-server重启或者扩容都不会有session丢失</li>
                            </ul>
                        </div>
                        <div class="bg-red-50 p-4 rounded-lg">
                            <h4 class="font-semibold text-red-700 mb-2 flex items-center">
                                <i class="fas fa-times-circle mr-2"></i>
                                缺点
                            </h4>
                            <p>增加了一次网络调用，并且需要修改应用代码;如将所有的getSession方法替换为从Redis查数据的方式，redis获取数据比内存慢很多</p>
                        </div>
                    </div>
                </div>
            </section>

            <!-- 分布式Session -->
            <section class="mb-16">
                <h2 class="text-3xl font-bold mb-6 text-gray-800 border-b pb-2 flex items-center">
                    <i class="fas fa-network-wired text-indigo-500 mr-3"></i>
                    分布式Session
                </h2>
                <p class="mb-6"><strong>分布式Session</strong> 就是我们的 Session 会话对于集群中的每个服务共享。我这里举一个例子：</p>
                
                <div class="bg-white rounded-lg overflow-hidden shadow-md mb-6">
                    <img src="https://cdn.nlark.com/yuque/0/2024/png/21449790/1711248177286-93d7c796-53dc-439c-9293-92459c005a0d.png" alt="分布式Session示例" class="w-full">
                </div>
                
                <p class="mb-6">假如一个商品服务通过2台机器 A和B 进行集群部署，用户访问 A服务器登录成功后，将此用户Session信息保存在 A 服务器上。突然A服务器突然宕机，用户访问跳转B服务器上。此时B服务器上并没有A服务的 Session。用户需要再次执行登录操作。</p>
                <p class="text-lg font-medium bg-blue-50 p-4 rounded-lg">而Spring Session 可以将用户登录后的Session 保存在Redis或者数据库中，当 A 服务器宕机切换到 B 服务器时，此时B服务器从Redis中获取Session,无需在进行登录操作。</p>
            </section>

            <!-- SpringSession简介 -->
            <section class="mb-16">
                <h2 class="text-3xl font-bold mb-6 text-gray-800 border-b pb-2 flex items-center">
                    <i class="fas fa-info-circle text-teal-500 mr-3"></i>
                    SpringSession简介
                </h2>
                
                <div class="code-block mb-6">
                    <pre class="text-sm">https://docs.spring.io/spring-session/docs/2.4.4/reference/html5/guides/boot-redis.html</pre>
                </div>
                
                <div class="bg-white rounded-lg p-6 shadow-sm mb-6">
                    <p class="mb-4">Spring Session是一个用于在Spring应用程序中管理会话数据的框架。它提供了一种简单的方式来实现分布式系统中的会话管理，以及将会话数据存储在外部存储系统中，如数据库、缓存或分布式数据存储。</p>
                    
                    <div class="bg-white rounded-lg overflow-hidden shadow-sm mb-4">
                        <img src="https://cdn.nlark.com/yuque/0/2024/png/21449790/1711248242626-7f87c8d4-b772-493f-a4e3-218bf3900ce7.png" alt="SpringSession架构" class="w-full">
                    </div>
                    
                    <p>Spring Session的主要目标是使会话管理变得更加灵活和可扩展，同时提供统一的API和配置方式，使开发人员能够轻松地集成和使用会话管理功能，而无需关心底层存储机制的细节。Spring Session提供了与Spring框架的无缝集成，并支持与Spring Security等其他Spring项目的集成，从而使开发人员能够更加方便地构建安全、可靠和高效的分布式应用程序。</p>
                </div>
            </section>

            <!-- SpringSession特性 -->
            <section class="mb-16">
                <h2 class="text-3xl font-bold mb-8 text-gray-800 border-b pb-2 flex items-center">
                    <i class="fas fa-star text-yellow-500 mr-3"></i>
                    SpringSession特性
                </h2>
                
                <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
                    <div class="flex">
                        <div class="feature-icon bg-blue-100 text-blue-500">
                            <i class="fas fa-layer-group text-xl"></i>
                        </div>
                        <div>
                            <h3 class="text-xl font-semibold mb-2">会话管理抽象</h3>
                            <p>Spring Session提供了会话管理的抽象层，使开发人员可以轻松地在Spring应用程序中管理会话数据。</p>
                        </div>
                    </div>
                    
                    <div class="flex">
                        <div class="feature-icon bg-purple-100 text-purple-500">
                            <i class="fas fa-sitemap text-xl"></i>
                        </div>
                        <div>
                            <h3 class="text-xl font-semibold mb-2">分布式会话管理</h3>
                            <p>Spring Session支持在分布式系统中管理会话数据，可以将会话数据存储在外部存储系统中，如数据库、缓存或分布式数据存储。</p>
                        </div>
                    </div>
                    
                    <div class="flex">
                        <div class="feature-icon bg-green-100 text-green-500">
                            <i class="fas fa-database text-xl"></i>
                        </div>
                        <div>
                            <h3 class="text-xl font-semibold mb-2">多种存储后端支持</h3>
                            <p>Spring Session支持多种会话存储后端，包括Redis、MongoDB、JDBC、Hazelcast等，开发人员可以根据项目需求选择合适的存储后端。</p>
                        </div>
                    </div>
                    
                    <div class="flex">
                        <div class="feature-icon bg-red-100 text-red-500">
                            <i class="fas fa-puzzle-piece text-xl"></i>
                        </div>
                        <div>
                            <h3 class="text-xl font-semibold mb-2">集成性</h3>
                            <p>Spring Session与Spring框架无缝集成，同时也支持与Spring Security等其他Spring项目的集成，可以方便地构建安全、可靠和高效的分布式应用程序。</p>
                        </div>
                    </div>
                    
                    <div class="flex">
                        <div class="feature-icon bg-indigo-100 text-indigo-500">
                            <i class="fas fa-code text-xl"></i>
                        </div>
                        <div>
                            <h3 class="text-xl font-semibold mb-2">统一的API和配置方式</h3>
                            <p>Spring Session提供了统一的API和配置方式，使开发人员能够轻松地集成和使用会话管理功能，而无需关心底层存储机制的细节。</p>
                        </div>
                    </div>
                    
                    <div class="flex">
                        <div class="feature-icon bg-pink-100 text-pink-500">
                            <i class="fas fa-bell text-xl"></i>
                        </div>
                        <div>
                            <h3 class="text-xl font-semibold mb-2">会话事件监听器</h3>
                            <p>Spring Session提供了会话事件监听器，开发人员可以通过监听器来监听会话的创建、销毁和过期等事件，从而实现更灵活的会话管理。</p>
                        </div>
                    </div>
                    
                    <div class="flex">
                        <div class="feature-icon bg-yellow-100 text-yellow-500">
                            <i class="fas fa-users text-xl"></i>
                        </div>
                        <div>
                            <h3 class="text-xl font-semibold mb-2">并发控制</h3>
                            <p>Spring Session支持并发控制，可以确保会话数据的一致性和可靠性，避免出现并发访问导致的数据不一致问题。</p>
                        </div>
                    </div>
                </div>
            </section>

            <!-- SpringBoot整合SpringSession -->
            <section class="mb-16">
                <h2 class="text-3xl font-bold mb-6 text-gray-800 border-b pb-2 flex items-center">
                    <i class="fas fa-plug text-red-500 mr-3"></i>
                    SpringBoot整合SpringSession
                </h2>
                
                <h3 class="text-2xl font-semibold mb-4 text-gray-800 flex items-center">
                    <i class="fas fa-cube text-red-400 mr-2"></i>
                    依赖
                </h3>
                <div class="code-block mb-6">
                    <pre class="text-sm">
&lt;dependency&gt;
    &lt;groupId&gt;org.springframework.session&lt;/groupId&gt;
    &lt;artifactId&gt;spring-session-data-redis&lt;/artifactId&gt;
&lt;/dependency&gt;

&lt;dependency&gt;
    &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
    &lt;artifactId&gt;spring-boot-starter-data-redis&lt;/artifactId&gt;
&lt;/dependency&gt;</pre>
                </div>
                
                <h3 class="text-2xl font-semibold mb-4 text-gray-800 flex items-center">
                    <i class="fas fa-file-code text-red-400 mr-2"></i>
                    yml
                </h3>
                <div class="code-block mb-6">
                    <pre class="text-sm">
server:
  port: 8001
  servlet:
    session:
      timeout: 30m # session超时时间，默认也是30m
spring:
  session:
    store-type: redis # session储存的位置
    redis:
      namespace: spring:session # session储存到redis的前缀
  redis:
    password: root
    host: 192.168.147.102</pre>
                </div>
                
                <h3 class="text-2xl font-semibold mb-4 text-gray-800 flex items-center">
                    <i class="fas fa-play-circle text-red-400 mr-2"></i>
                    主启动类开启配置
                </h3>
                <div class="code-block mb-6">
                    <pre class="text-sm">
@EnableRedisHttpSession
@SpringBootApplication(scanBasePackages = "com.ts")
public class SpringSession01Application {
    public static void main(String[] args) {
        SpringApplication.run(SpringSession01Application.class, args);
    }
}</pre>
                </div>
                
                <h3 class="text-2xl font-semibold mb-4 text-gray-800 flex items-center">
                    <i class="fas fa-user text-red-400 mr-2"></i>
                    User
                </h3>
                <div class="code-block mb-6">
                    <pre class="text-sm">
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private String username;
}</pre>
                </div>
                
                <h3 class="text-2xl font-semibold mb-4 text-gray-800 flex items-center">
                    <i class="fas fa-terminal text-red-400 mr-2"></i>
                    Controller
                </h3>
                <div class="code-block mb-6">
                    <pre class="text-sm">
@RestController
@RequestMapping("/user")
public class UserController {

    @RequestMapping("/login")
    public String login(String username, String password, HttpServletRequest request) {
        if ("admin".equals(username) && "admin".equals(password)) {
            request.getSession().setAttribute("user", new User(username));
            return "success --> "+System.currentTimeMillis();
        } else {
            return "error --> "+System.currentTimeMillis();
        }
    }

    @GetMapping("/getUser")
    public String getUser(HttpServletRequest request) {
        Object user = request.getSession().getAttribute("user");
        if(user == null){
            return "你还没有登录";
        }
        return user.toString() +" --> "+System.currentTimeMillis();
    }
}</pre>
                </div>
                
                <h3 class="text-2xl font-semibold mb-4 text-gray-800 flex items-center">
                    <i class="fas fa-server text-red-400 mr-2"></i>
                    在启动一个服务模拟集群
                </h3>
                <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6">
                    <div class="bg-white rounded-lg overflow-hidden shadow-sm">
                        <img src="https://cdn.nlark.com/yuque/0/2023/png/21449790/1692180731714-f27aa231-2c88-4333-9023-de9afcfddf52.png" alt="集群配置1" class="w-full">
                    </div>
                    <div class="bg-white rounded-lg overflow-hidden shadow-sm">
                        <img src="https://cdn.nlark.com/yuque/0/2023/png/21449790/1692180731800-f7d6ac5a-1107-4e45-9a95-7840d3f80f25.png" alt="集群配置2" class="w-full">
                    </div>
                </div>
                
                <h3 class="text-2xl font-semibold mb-4 text-gray-800 flex items-center">
                    <i class="fas fa-vial text-red-400 mr-2"></i>
                    测试
                </h3>
                <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6">
                    <div class="bg-white rounded-lg overflow-hidden shadow-sm">
                        <img src="https://cdn.nlark.com/yuque/0/2023/png/21449790/1692180731884-a16cb1f0-6942-44b1-9bc2-d609daa081df.png" alt="测试结果1" class="w-full">
                    </div>
                    <div class="bg-white rounded-lg overflow-hidden shadow-sm">
                        <img src="https://cdn.nlark.com/yuque/0/2023/png/21449790/1692180732004-6f7751dc-ed2b-4dbd-a75b-5b35109327be.png" alt="测试结果2" class="w-full">
                    </div>
                </div>
            </section>

            <!-- 使用JSON序列化 -->
            <section class="mb-16">
                <h2 class="text-3xl font-bold mb-6 text-gray-800 border-b pb-2 flex items-center">
                    <i class="fas fa-code text-blue-500 mr-3"></i>
                    使用JSON序列化
                </h2>
                <p class="mb-6">使用JSON序列化保存到redis信息及时一个JSON字符串</p>
                
                <div class="code-block mb-6">
                    <pre class="text-sm">
@Configuration
public class SpringSessionConfig {
    /**
     * JSON序列化 - 使用FastJson，需要引入Fastjson的依赖
     */
    @Bean
    public RedisSerializer&lt;Object&gt; springSessionDefaultRedisSerializer(){
        return new GenericFastJsonRedisSerializer();
    }
    
     /**
     * 解决Cookie跨域问题
     */
    @Bean
    public CookieSerializer cookieSerializer(){
        DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer();
        cookieSerializer.setDomainName("ts.com");
        cookieSerializer.setCookieName("sessionId");  // 自定义SessionId
        return cookieSerializer;
    }
}</pre>
                </div>
                
                <div class="code-block mb-6">
                    <pre class="text-sm">
&lt;dependency&gt;
    &lt;groupId&gt;com.alibaba&lt;/groupId&gt;
    &lt;artifactId&gt;fastjson&lt;/artifactId&gt;
    &lt;version&gt;1.2.76&lt;/version&gt;
&lt;/dependency&gt;</pre>
                </div>
            </section>

            <!-- SpringSession原理 -->
            <section class="mb-16">
                <h2 class="text-3xl font-bold mb-6 text-gray-800 border-b pb-2 flex items-center">
                    <i class="fas fa-cogs text-indigo-500 mr-3"></i>
                    SpringSession原理
                </h2>
                <p class="mb-6">SpringSession核心对象有两个</p>
                
                <div class="bg-white rounded-lg p-6 shadow-sm mb-6">
                    <h3 class="text-2xl font-semibold mb-4 text-gray-800">1. <strong>SessionRepository：</strong></h3>
                    <p class="mb-4">它是 Spring Session 框架中的一个核心接口，用于定义会话存储库的行为。它提供了对会话数据的创建、获取、更新和删除等操作，并隐藏了底层存储后端的细节，使开发人员能够通过统一的接口来管理会话数据。SessionRepository 接口通常由存储后端的具体实现类来实现，如基于Redis、MongoDB、JDBC等的存储后端。通过实现 SessionRepository 接口，开发人员可以轻松地集成 Spring Session 到自己的应用程序中，并选择适合自己需求的存储后端，从而实现可靠的分布式会话管理功能。</p>
                    
                    <div class="bg-white rounded-lg overflow-hidden shadow-sm mb-4">
                        <img src="https://cdn.nlark.com/yuque/0/2023/png/21449790/1692180732096-a5ab4a2f-7cdc-4429-bc9a-a26952908799.png" alt="SessionRepository" class="w-full">
                    </div>
                </div>
                
                <div class="bg-white rounded-lg p-6 shadow-sm mb-6">
                    <h3 class="text-2xl font-semibold mb-4 text-gray-800">2. <strong>SessionRepositoryFilter：</strong></h3>
                    <p class="mb-4">它是 Spring Session 框架提供的一个过滤器，用于拦截 Web 请求，并将当前请求关联的会话信息存储到指定的会话存储库中。它主要用于将 Servlet 容器的 HttpSession 与 Spring Session 的会话存储库进行关联，从而实现对分布式会话的管理。在 Web 应用中，通过配置 SessionRepositoryFilter 可以让 Spring Session 框架自动处理会话数据的存储和管理，而不需要开发人员手动操作 HttpSession。通过 SessionRepositoryFilter，开发人员可以轻松地实现会话的跨服务器、跨容器的共享和管理，从而提高应用程序的可伸缩性和可靠性。</p>
                    
                    <div class="bg-white rounded-lg overflow-hidden shadow-sm mb-4">
                        <img src="https://cdn.nlark.com/yuque/0/2023/png/21449790/1692180732210-173c3036-b42b-420d-bbc8-e0a3dbec9e4b.png" alt="SessionRepositoryFilter" class="w-full">
                    </div>
                    
                    <p class="mb-4">拦截所有的请求</p>
                    
                    <div class="bg-white rounded-lg overflow-hidden shadow-sm mb-4">
                        <img src="https://cdn.nlark.com/yuque/0/2023/png/21449790/1692180732322-6af592fa-03bf-4a37-9bc1-02b4f43def6b.png" alt="SessionRepositoryFilter拦截请求" class="w-full">
                    </div>
                    
                    <p class="mb-4">复写了getSession方法，在这个中从redis中读取session。</p>
                    
                    <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
                        <div class="bg-white rounded-lg overflow-hidden shadow-sm">
                            <img src="https://cdn.nlark.com/yuque/0/2023/png/21449790/1692180732427-6b92eaae-9f87-42bd-a36b-d58576aa0c47.png" alt="getSession方法" class="w-full">
                        </div>
                        <div class="bg-white rounded-lg overflow-hidden shadow-sm">
                            <img src="https://cdn.nlark.com/yuque/0/2023/png/21449790/1692180732556-a580d1cf-7801-45b8-9f56-86074d005fe0.png" alt="getSession方法实现" class="w-full">
                        </div>
                    </div>
                </div>
                
                <div class="bg-white rounded-lg p-6 shadow-sm">
                    <h3 class="text-2xl font-semibold mb-4 text-gray-800">3. <strong>SessionRepositoryRequestWrapper：</strong></h3>
                    <p>实现了HttpServletRequest接口，是SpringSession中调用的session，而并不是原生的session。</p>
                </div>
            </section>
        </div>
    </main>

    <!-- Footer -->
    <footer class="bg-gray-900 text-white py-8">
        <div class="container mx-auto px-4 text-center">
            <div class="mb-4">
                <h3 class="text-xl font-bold">技术小馆</h3>
            </div>
            <div>
                <a href="http://www.yuque.com/jtostring" class="text-gray-300 hover:text-white transition-colors duration-300">
                    <i class="fas fa-globe mr-2"></i>http://www.yuque.com/jtostring
                </a>
            </div>
        </div>
    </footer>

    <script>
        mermaid.initialize({
            startOnLoad: true,
            theme: 'default',
            flowchart: {
                useMaxWidth: true,
                htmlLabels: true,
                curve: 'basis'
            }
        });
    </script>
</body>
</html>
```